using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using DataLayerUtilities;

namespace DataServices
{
	/// <summary>
	/// Summary description for DataSourceManager.
	/// </summary>
	public class DataSourceManager
	{
		static XmlDocument configuration;
		static Hashtable DataSources = new Hashtable(); 
		static string encryptKey = "x8Jhjk56";

		private static XmlDocument CreateConfiguration()
		{
			MemoryStream ms = new MemoryStream(1024);
			XmlTextWriter writer = new XmlTextWriter(ms,Encoding.Unicode);
			writer.Formatting = Formatting.Indented;
			writer.WriteStartDocument();
				writer.WriteStartElement("DataServices");
					//DataSources
					writer.WriteStartElement("DataSources");
						writer.WriteStartElement("DataSource");
							writer.WriteAttributeString("Name","SIA");
							writer.WriteAttributeString("ProviderType","SQLProvider");
								writer.WriteElementString("Username",EncryptionServices.Encrypt("sa",encryptKey));
								writer.WriteElementString("Password",EncryptionServices.Encrypt("xseries235",encryptKey));
								writer.WriteElementString("Host",EncryptionServices.Encrypt("localhost",encryptKey));
								writer.WriteElementString("Port",EncryptionServices.Encrypt("1433",encryptKey));
								writer.WriteElementString("DataBase",EncryptionServices.Encrypt("SIA",encryptKey));		
						writer.WriteEndElement();
						writer.WriteStartElement("DataSource");
								writer.WriteAttributeString("Name","Northwind");
								writer.WriteAttributeString("ProviderType","SQLProvider");
								writer.WriteElementString("Username",EncryptionServices.Encrypt("sa",encryptKey));
								writer.WriteElementString("Password",EncryptionServices.Encrypt("xseries235",encryptKey));
								writer.WriteElementString("Host",EncryptionServices.Encrypt("localhost",encryptKey));
								writer.WriteElementString("Port",EncryptionServices.Encrypt("1433",encryptKey));
								writer.WriteElementString("DataBase",EncryptionServices.Encrypt("Northwind",encryptKey));		
						writer.WriteEndElement();
						writer.WriteStartElement("DataSource");
								writer.WriteAttributeString("Name","SIT");
								writer.WriteAttributeString("ProviderType","SQLProvider");
								writer.WriteElementString("Username",EncryptionServices.Encrypt("sit",encryptKey));
								writer.WriteElementString("Password",EncryptionServices.Encrypt("sitpl370",encryptKey));
								writer.WriteElementString("Host",EncryptionServices.Encrypt("localhost",encryptKey));
								writer.WriteElementString("Port",EncryptionServices.Encrypt("1433",encryptKey));
								writer.WriteElementString("DataBase",EncryptionServices.Encrypt("SIT",encryptKey));		
						writer.WriteEndElement();
						writer.WriteStartElement("DataSource");
								writer.WriteAttributeString("Name","Ayuntamiento");
								writer.WriteAttributeString("ProviderType","PGProvider");
								writer.WriteElementString("Username",EncryptionServices.Encrypt("ayuntamiento",encryptKey));
								writer.WriteElementString("Password",EncryptionServices.Encrypt("123ayunta",encryptKey));
								writer.WriteElementString("Host",EncryptionServices.Encrypt("localhost",encryptKey));
								writer.WriteElementString("Port",EncryptionServices.Encrypt("5432",encryptKey));
								writer.WriteElementString("DataBase",EncryptionServices.Encrypt("ayuntamiento",encryptKey));		
						writer.WriteEndElement();
						writer.WriteStartElement("DataSource");
								writer.WriteAttributeString("Name","TWare");
								writer.WriteAttributeString("ProviderType","MySQLProvider");
								writer.WriteElementString("Username",EncryptionServices.Encrypt("tware",encryptKey));
								writer.WriteElementString("Password",EncryptionServices.Encrypt("twarex",encryptKey));
								writer.WriteElementString("Host",EncryptionServices.Encrypt("127.0.0.1",encryptKey));
								writer.WriteElementString("Port",EncryptionServices.Encrypt("3360",encryptKey));
								writer.WriteElementString("DataBase",EncryptionServices.Encrypt("tware",encryptKey));		
						writer.WriteEndElement();
					writer.WriteEndElement();
					//ProviderTypes
					writer.WriteStartElement("ProviderTypes");
						writer.WriteElementString("ProviderType","SQLProvider");
						writer.WriteElementString("ProviderType","PGProvider");
						writer.WriteElementString("ProviderType","MySQLProvider");
					writer.WriteEndElement();
				writer.WriteEndElement();
			writer.WriteEndDocument();
			writer.Flush();
			ms.Flush();
			
			ms.Position = 0;

			XmlDocument doc = null;
		
			try
			{
				doc = new XmlDocument();
				doc.Load(ms);
			}
			catch (XmlException ex)
			{
				Debug.WriteLine(ex.Message);
			}
			
			return doc;
		}
		
		private static XmlDocument XmlConfiguration
		{
			get
			{
				if (configuration==null)
				{
					string strPath = Path.GetDirectoryName(
						Assembly.GetExecutingAssembly().Location);
					
					if (! File.Exists(strPath + "\\DataServices.config"))
					{
						configuration = CreateConfiguration();
						XmlTextWriter xw = new XmlTextWriter(strPath + "\\DataServices.config",Encoding.Unicode);
						xw.Formatting = Formatting.Indented;
						configuration.WriteContentTo(xw);
						xw.Close();
					} 
					else
					{
						configuration = new XmlDocument();
						configuration.Load(strPath + "\\DataServices.config");
					}

					//Decrypt the information encrypted in the file
					XmlNodeList nodes = configuration.GetElementsByTagName("Username");
					for (int x=0;x<nodes.Count;x++)
						nodes[x].InnerText = EncryptionServices.Decrypt(nodes[x].InnerText,encryptKey);

					nodes = configuration.GetElementsByTagName("Password");
					for (int x=0;x<nodes.Count;x++)
						nodes[x].InnerText = EncryptionServices.Decrypt(nodes[x].InnerText,encryptKey);

					nodes = configuration.GetElementsByTagName("Host");
					for (int x=0;x<nodes.Count;x++)
						nodes[x].InnerText = EncryptionServices.Decrypt(nodes[x].InnerText,encryptKey);

					nodes = configuration.GetElementsByTagName("Port");
					for (int x=0;x<nodes.Count;x++)
						nodes[x].InnerText = EncryptionServices.Decrypt(nodes[x].InnerText,encryptKey);

					nodes = configuration.GetElementsByTagName("DataBase");
					for (int x=0;x<nodes.Count;x++)
						nodes[x].InnerText = EncryptionServices.Decrypt(nodes[x].InnerText,encryptKey);


				}
				return configuration;
			}
		}

        
		
		public static DataSource CreateDataSource(string key, Type tipo, string connName)
		{
			DataSource ds = null;

			if (GetDataSource(key)==null)
			{
				XmlNodeList nodos = XmlConfiguration.GetElementsByTagName("DataSource");
				XmlNode nodoDs = null;
				foreach (XmlNode nodo in nodos)
				{
					if (nodo.Attributes.GetNamedItem("Name").InnerText == connName)
						nodoDs = nodo;
				}

				if (nodoDs!=null)
				{
					if (typeof(SqlDataSource)==tipo)
					{
						string connStr = SqlDataSource.ConnectionStringBuilder(	nodoDs.ChildNodes[0].InnerText,
							nodoDs.ChildNodes[1].InnerText,
							nodoDs.ChildNodes[2].InnerText,
							nodoDs.ChildNodes[4].InnerText
							);
						ds = new SqlDataSource(connStr,key);
						
					} else if ( typeof(PgSqlDataSource) == tipo )
					{
						string connStr = PgSqlDataSource.ConnectionStringBuilder(	nodoDs.ChildNodes[0].InnerText,
							nodoDs.ChildNodes[1].InnerText,
							nodoDs.ChildNodes[2].InnerText,
							nodoDs.ChildNodes[4].InnerText
							);
						ds = new PgSqlDataSource(connStr, key);
					}  else if ( typeof(MySqlDataSource) == tipo )
					{
						string connStr = MySqlDataSource.ConnectionStringBuilder(	nodoDs.ChildNodes[0].InnerText,
							nodoDs.ChildNodes[1].InnerText,
							nodoDs.ChildNodes[2].InnerText,
							nodoDs.ChildNodes[4].InnerText
							);
						ds = new MySqlDataSource(connStr, key);
					}
					DataSources.Add(key,ds);
				} 
			} else
				ds = GetDataSource(key);

			return ds;
		}

        public static DataSource GetDataSource(string key)
        {
            DataSource ds = null;
			
			if (DataSources.ContainsKey(key))
            {
            	ds = (DataSource)DataSources[key];
            }

			return ds;	
        }
		
		public IDictionaryEnumerator DataSourcesEnumerator
		{
			get
			{
				return DataSources.GetEnumerator();
			}
		}

		public static int DataSourcesCount
		{
			get
			{
				return DataSources.Count;
			}
		}

		public static bool RemoveDataSource(string key)
		{
			if (DataSources.ContainsKey(key))
			{
				DataSources.Remove(key);
				return true;
			}
				
			return false;
		}

		public static bool RemoveDataSource(DataSource ds)
		{
			if (DataSources.ContainsKey(ds.Key))
			{
				DataSources.Remove(ds.Key);
				return true;
			}

			return false;
		}
		
	}
}
